home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
SHDK_1
/
SHCRCCHK.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-03-23
|
8KB
|
210 lines
{$A-}
unit ShCrcChk;
{
ShCrcChk
A File CRC16 Calculation Unit
by
Bill Madison
W. G. Madison and Associates, Ltd.
13819 Shavano Downs
P.O. Box 780956
San Antonio, TX 78278-0956
(512)492-2777
CIS 73240,342
Copyright 1991 Madison & Associates
All Rights Reserved
This file may be used and distributed only in accord-
ance with the provisions described on the title page of
the accompanying documentation file
SKYHAWK.DOC
}
Interface
Uses
DOS;
Function CrcCalc(FileName : String) : word;
{
Calculates the CCITT asynch CRC16 value for file = FileName.
}
Function CrcCopy(InFileName, OutFileName : String) : word;
{
Calculates the CCITT asynch CRC16 value for file=InFileName. If
OutFileName is specified, InFileName is copied to OutFileName. In either
case, the CRC16 value is returned.
}
Implementation
var
Buff : array[1..16384] of Byte; {The data buffer}
{Note: Extensive testing has determined that only a slight
speed-up can be achieved by increasing the buffer size
further. }
const
CrcTab : array[0..255] of Word =
($0000,$1021,$2042,$3063,$4084,$50A5,$60C6,$70E7,
$8108,$9129,$A14A,$B16B,$C18C,$D1AD,$E1CE,$F1EF,
$1231,$0210,$3273,$2252,$52B5,$4294,$72F7,$62D6,
$9339,$8318,$B37B,$A35A,$D3BD,$C39C,$F3FF,$E3DE,
$2462,$3443,$0420,$1401,$64E6,$74C7,$44A4,$5485,
$A56A,$B54B,$8528,$9509,$E5EE,$F5CF,$C5AC,$D58D,
$3653,$2672,$1611,$0630,$76D7,$66F6,$5695,$46B4,
$B75B,$A77A,$9719,$8738,$F7DF,$E7FE,$D79D,$C7BC,
$48C4,$58E5,$6886,$78A7,$0840,$1861,$2802,$3823,
$C9CC,$D9ED,$E98E,$F9AF,$8948,$9969,$A90A,$B92B,
$5AF5,$4AD4,$7AB7,$6A96,$1A71,$0A50,$3A33,$2A12,
$DBFD,$CBDC,$FBBF,$EB9E,$9B79,$8B58,$BB3B,$AB1A,
$6CA6,$7C87,$4CE4,$5CC5,$2C22,$3C03,$0C60,$1C41,
$EDAE,$FD8F,$CDEC,$DDCD,$AD2A,$BD0B,$8D68,$9D49,
$7E97,$6EB6,$5ED5,$4EF4,$3E13,$2E32,$1E51,$0E70,
$FF9F,$EFBE,$DFDD,$CFFC,$BF1B,$AF3A,$9F59,$8F78,
$9188,$81A9,$B1CA,$A1EB,$D10C,$C12D,$F14E,$E16F,
$1080,$00A1,$30C2,$20E3,$5004,$4025,$7046,$6067,
$83B9,$9398,$A3FB,$B3DA,$C33D,$D31C,$E37F,$F35E,
$02B1,$1290,$22F3,$32D2,$4235,$5214,$6277,$7256,
$B5EA,$A5CB,$95A8,$8589,$F56E,$E54F,$D52C,$C50D,
$34E2,$24C3,$14A0,$0481,$7466,$6447,$5424,$4405,
$A7DB,$B7FA,$8799,$97B8,$E75F,$F77E,$C71D,$D73C,
$26D3,$36F2,$0691,$16B0,$6657,$7676,$4615,$5634,
$D94C,$C96D,$F90E,$E92F,$99C8,$89E9,$B98A,$A9AB,
$5844,$4865,$7806,$6827,$18C0,$08E1,$3882,$28A3,
$CB7D,$DB5C,$EB3F,$FB1E,$8BF9,$9BD8,$ABBB,$BB9A,
$4A75,$5A54,$6A37,$7A16,$0AF1,$1AD0,$2AB3,$3A92,
$FD2E,$ED0F,$DD6C,$CD4D,$BDAA,$AD8B,$9DE8,$8DC9,
$7C26,$6C07,$5C64,$4C45,$3CA2,$2C83,$1CE0,$0CC1,
$EF1F,$FF3E,$CF5D,$DF7C,$AF9B,$BFBA,$8FD9,$9FF8,
$6E17,$7E36,$4E55,$5E74,$2E93,$3EB2,$0ED1,$1EF0);
Function CRCResult(Var Table, Buffer; CrcVal, count : integer) : integer;
var temp : integer;
begin
Inline(
{For I := 1 to Full do
CRCval := Crctab[hi(CRCval) xor Buff[I]] xor (lo(CRCval) shl 8);}
$1E/ { push ds ;save ds}
$06/ { push es ;save es}
$C5/$B6/>TABLE/ { lds si, [bp+>Table] ;ds:si points to the table}
$C4/$BE/>BUFFER/ { les di, [bp+>buffer] ;es:si points to the buffer}
$8B/$8E/>COUNT/ { mov cx,[bp+>count] ;cx has the buffer size}
$8B/$9E/>CRCVAL/ { mov bx,[bp+>CRCVal] ;bx = start CRC value}
$E3/$25/ { jcxz Done}
$89/$D8/ { mov ax,bx ;ax = start CRC value}
{ LooPit:}
$86/$C4/ { xchg ah,al ;al = hi byte}
$30/$E4/ { xor ah,ah ;ax = hi(CRCVal)}
$31/$D2/ { xor dx,dx ;dx = 0}
$26/ { es:}
$8A/$15/ { mov dl,[di] ;dx = buffer[i] A BYTE value!!}
$47/ { inc di ;bump di (inc(i))}
$31/$D0/ { xor ax,dx ;ax = hi(CRCVal) xor Buffer[i]}
$89/$DA/ { mov dx,bx ;dx = CRCVal}
$89/$C3/ { mov bx,ax ;bx = hi(CRCVal) xor Buffer[i]}
$30/$F6/ { xor dh,dh ;dx = lo(CRCVal)}
$51/ { push cx ;save counter}
$B1/$08/ { mov cl,8 ;need 8 shifts}
$D3/$E2/ { shl dx,cl ;dx = lo(CRCVal) shl 8}
$59/ { pop cx ;restore the counter}
$D1/$E3/ { shl bx,1 ;need to mult by 2}
$3E/ { ds:}
$8B/$00/ { mov ax,[bx+si] ;ax = CRCTAbl[hi(CRCVal xor Buffer[i]]}
$31/$D0/ { xor ax,dx ;ax = CRCTab[hi(CRCVal) xor Buffer[i]]}
{ ; xor (lo(CRCVal) shl 8)}
$89/$C3/ { mov bx,ax ;bx = new CRCVal}
$E2/$DD/ { loop loopit ;go do it all again}
{ Done:}
$89/$9E/>TEMP/ { mov [bp+>temp],bx ;bx has the final CRC value}
$07/ { pop es ;restore es}
$1F); { pop ds ;restore ds}
CRCResult := temp{ ;pass it back}
end; {CrcResult}
Function CrcCalc(FileName : String) : word;
var
FI : File;
Full : Integer; {How full is the buffer on a block read?}
CRCval : Integer;
FileAttr: word;
begin {CrcCalc}
CrcVal := 0;
Assign(FI, FileName);
GetFAttr(FI, FileAttr);
SetFAttr(FI, 0); {can now open any file}
Reset(FI, 1);
repeat
BlockRead(FI, Buff, 16384, Full);
CrcVal := CrcResult(CrcTab, Buff, CrcVal, Full);
until Full <= 0;
Close(FI);
SetFAttr(FI, FileAttr); {restore original filemode}
CrcCalc := CRCval;
end; {CrcCalc}
Function CrcCopy(InFileName, OutFileName : String) : word;
{
Calculates the CCITT asynch CRC16 value for file=InFileName. If
OutFileName is specified, InFileName is copied to OutFileName. In either
case, the CRC16 value is returned. The DateTime stamp of the input file
is preserved.
}
var
FI,
FO : File;
Full : Integer; {Number of bytes transferred in BlockRead}
T1 : Integer;
CRCval : Integer;
DTStamp: LongInt;
FileAttr: word;
begin {CrcCopy}
CrcVal := 0;
Assign(FI, InFileName);
GetFattr(FI, FileAttr);
SetFAttr(FI, 0); {can now open any file}
Reset(FI, 1);
If OutFileName[0] > #0 then begin
Assign(FO, OutFileName);
{$I-}Rewrite(FO, 1);{$I+}
If IOresult <> 0 then begin
WriteLn;
WriteLn('Can''t open file ',OutFileName,' Aborting...');
Halt(1);
end;
end;
repeat
BlockRead(FI, Buff, 16384, Full);
CrcVal := CrcResult(CrcTab, Buff, CrcVal, Full);
If (OutFileName[0] > #0) and (Full > 0) then
{$I-}BlockWrite(FO, Buff, Full);{$I+}
T1 := IOresult;
If T1 <> 0 then begin
WriteLn;
WriteLn('I/O error ',T1,' writing file. Aborting...');
Close(FO);
Erase(FO);
Halt(1);
end;
until Full <= 0;
GetFTime(FI, DTstamp);
Close(FI);
SetFAttr(FI, FileAttr); {restore original filemode}
If OutFileName[0] > #0 then begin
SetFTime(FO, DTstamp);
Close(FO);
end;
CrcCopy := CRCval;
end; {CrcCopy}
end.